public class Zombie {

  int fingerId = -1;
  float durationBetweenEachFrame;
  int previousUpdate, currentImage = 0;
  PImage stillImages[], movingImages[], action1[];
  float scaleValue = 1, xScale = 1.0, yScale = 1.0;
  PVector startingLocation, destination = new PVector(0,0), currentLocation = new PVector(0,0), velocity = new PVector(0,0);
  boolean isMoving = false, isAttacking = false;;;
  float xDistance, yDistance, attackRadius, currentAngle = 0, previousMoveTime = 0, durationBetweenEachMove;
  int actionImage = 0, lastSwing = 0;
  float radiusOfCastle = 162*width/1920.0;
  PVector center = new PVector(width/2.0, height/2.0);
  
  public Zombie(PImage stillImages[], PImage movingImages[], PImage action1[], float durationBetweenEachFrame, float durationBetweenEachMove, PVector startingLocation, float attackRadius){
    previousUpdate = millis();
    this.durationBetweenEachFrame = durationBetweenEachFrame;
    this.stillImages = stillImages;
    this.movingImages = movingImages;
    this.startingLocation = startingLocation;
    this.currentLocation.add(startingLocation);
    this.attackRadius = attackRadius;
    this.action1 = action1;
    this.durationBetweenEachMove = durationBetweenEachMove;
  }

  void setScale(float xScale, float yScale){
    this.xScale = xScale;
    this.yScale = yScale;
  }

  boolean isAttackPointInRange(PVector touch){
    if(touch.dist(currentLocation) < attackRadius){
      return true;
    } else {
      return false; 
    }
  }

  void update(int currentTime){
    if(currentTime - previousUpdate > durationBetweenEachFrame){
      if(currentImage >= stillImages.length-1){
        currentImage = 0;  
      }
      else {
        currentImage++;
      }
      previousUpdate = currentTime;
    }
    pushMatrix();
    translate(currentLocation.x, currentLocation.y);
    rotate(currentAngle);
    image(stillImages[currentImage], 0, 0);
    popMatrix();
  }
  
  void startSwing(int currentTime){
    isAttacking = true;
    isMoving = false;
    lastSwing = currentTime;
  }
  
  void setLocation(PVector location){
    startingLocation = location;
    currentLocation.x = 0;
    currentLocation.y = 0;
   currentLocation.add(startingLocation);
  }
  
  void attack(int currentTime){
    if(currentTime - lastSwing > durationBetweenEachFrame){
      if(actionImage >= action1.length-1){
        actionImage = 0;  
        //isAttacking = false;
      }
      else {        
        actionImage++;
      }
      lastSwing = currentTime;
    }
    pushMatrix();
    translate(currentLocation.x, currentLocation.y);
    rotate(currentAngle);
    image(action1[actionImage], 0, 0);
    popMatrix();
  }

  boolean isMoving(){
    return isMoving; 
  }
  
  boolean isAttacking(){
   return isAttacking; 
  }

  void setVelocity(PVector destination){
    float maxVelocity = 2;
    startingLocation.x = currentLocation.x;
    startingLocation.y = currentLocation.y;
    this.destination = destination; 
    xDistance = destination.x - startingLocation.x;
    yDistance = destination.y - startingLocation.y;
    if((xDistance == 0) && (yDistance == 0)) {
      isMoving = false;
    } else {
      isMoving = true;
      isAttacking = false; 
      float currentRadius = destination.dist(currentLocation);
      if((xDistance < 0) && (yDistance > 0)){
        currentAngle = PI/2 + acos(xDistance/currentRadius);
      } 
      else if ((xDistance < 0) && (yDistance < 0)){
        currentAngle = 5*PI/2 - acos(xDistance/currentRadius);
      } 
      else if ((xDistance > 0) && (yDistance < 0)) {
        currentAngle = PI/2 - acos(xDistance/currentRadius);
      } 
      else if((xDistance > 0) && (yDistance > 0)) {
        currentAngle = PI/2 + acos(xDistance/currentRadius);
      }
      if(xDistance < 0){
        velocity.x = -maxVelocity*(abs(xDistance)/(abs(yDistance) + abs(xDistance)));
      } else {
        velocity.x = maxVelocity*(abs(xDistance)/(abs(yDistance) + abs(xDistance))); 
      } 
      if(yDistance < 0){
        velocity.y = -maxVelocity*(abs(yDistance)/(abs(yDistance) + abs(xDistance)));
      } else {
        velocity.y = maxVelocity*(abs(yDistance)/(abs(yDistance) + abs(xDistance))); 
      }   
    }
  }

  void updatePosition(int currentTime){
    float xDestination = destination.x;
    float yDestination = destination.y;
    xDistance = destination.x - startingLocation.x;
    yDistance = destination.y - startingLocation.y;
    if(currentTime - previousMoveTime > durationBetweenEachMove){
      currentLocation.add(velocity);
      checkIfNearCaslte();
      previousMoveTime = currentTime;
    }
    if(currentTime - previousUpdate > durationBetweenEachFrame){
      if(currentImage >= movingImages.length-1){
        currentImage = 0;  
      }
      else {
        currentImage++;
      }
      previousUpdate = currentTime;
    }
  }

  private void checkIfNearCaslte(){
    if(currentLocation.dist(center) < radiusOfCastle){
      velocity.x = 0;
      velocity.y = 0;
      isAttacking = true;
    }
  }

  void moveToAreaThroughAnimation(){
    pushMatrix();
    translate(currentLocation.x, currentLocation.y);
    rotate(currentAngle);
    image(movingImages[currentImage], 0, 0);
    popMatrix();
  }
}



